
package com.ibm.broker.as400plugin;

import java.io.*;
import java.util.Calendar;

import com.ibm.broker.plugin.MbBrokerException;
import com.ibm.broker.plugin.MbElement;
import com.ibm.broker.plugin.MbException;
import com.ibm.broker.plugin.MbMessage;
import com.ibm.broker.plugin.MbMessageAssembly;

/*
Avoid multiple instances of logData...as multiple instaces of flow can exist:-)
*/
public class LogTraceData
{

 
 public static final int LOGDATA_LEVEL_NONE=0; /*no trace file created*/
 public static final int LOGDATA_LEVEL_ERROR=1; /*trace logs only errors*/
 public static final int LOGDATA_LEVEL_INFO=2; /*trace logs errors and some basic info of broker transaction*/
 public static final int LOGDATA_LEVEL_DEBUG=3; /*trace logs error,info,debug*/

 private int logLevelAct;
 private int logLevel; /*indicates NONE,INFO,ERROR,DEBUG*/
 private BufferedWriter logFileWriter = null;

 public static LogTraceData ld = null;
 
 public LogTraceData(String path)
 {
   //super();
   setlogDataLevel("NONE");/*Defualt is NONE internally*/

   try
   {
   	logFileWriter = new BufferedWriter(new FileWriter(path,true));
   }
   catch(IOException ioe) 
   {
	logData_Error(" IOException occurred while initializing the logFile ",ioe);
//	OSLogData.syslog(className,"logData",OSLogData.SYSLOG_WARN,"INTERNAL_UNKNOWN_WARN",this.getExceptionString(ioe));
   }
 }

 public int getlogDataLevel()
 {
   return logLevel;
 }
 /*set the logLevel*/
 public void setlogDataLevel(String Level)
 {
	try
	{ 	
   		logLevel = getlogDataLevelValue(Level);
   }catch(Exception e)
	{
//		OSLogData.syslog(className,"setlogDataLevel",OSLogData.SYSLOG_WARN,"INTERNAL_UNKNOWN_WARN",this.getExceptionString(e));
   }
 }
/*Various logging methos...INFO, ERROR, DEBUG..under normal situations*/ 
public void logData_Info(Object message) 
 {
 	this.logLevelAct = LOGDATA_LEVEL_INFO;
	if (logLevel >= LOGDATA_LEVEL_INFO)
   		logDataPrint(message,null);
 }
 
 public void logData_Debug(Object message) 
 {
	 this.logLevelAct = LOGDATA_LEVEL_DEBUG;
	 if (logLevel >= LOGDATA_LEVEL_DEBUG)
  		logDataPrint(message,null);
 }
 
 public void logData_Error(Object message)
 {
	 this.logLevelAct = LOGDATA_LEVEL_ERROR;
 	if (logLevel >= LOGDATA_LEVEL_ERROR)
  		logDataPrint(message,null);
 }
 /*Various logging methods...INFO, ERROR, DEBUG under exception situations*/ 
 public void logData_Info(Object message, Throwable exception) 
 {
	 this.logLevelAct = LOGDATA_LEVEL_INFO;
 	if (logLevel >= LOGDATA_LEVEL_INFO)
   		logDataPrint(message,exception);
 }
 
 public void logData_Debug(Object message, Throwable exception)
 {
	 this.logLevelAct = LOGDATA_LEVEL_DEBUG;
 	if (logLevel >= LOGDATA_LEVEL_DEBUG)
  		logDataPrint(message,exception);
 }
 
 public void logData_Error(Object message, Throwable exception) 
 {
	 this.logLevelAct = LOGDATA_LEVEL_ERROR;
 	if (logLevel >= LOGDATA_LEVEL_ERROR)
  		logDataPrint(message,exception);
 }
 /*This is the actual method that writes into the file */
 private void logDataPrint(Object message, Throwable exception)
 {
  /*This shd. write into file...*/
  if (logLevel == LOGDATA_LEVEL_NONE)  
  	return;

   	StringBuffer bf = new StringBuffer();
   	//String threadTime = getThreadTime();
	bf.append("[ "+getlogDataLevelInfo(this.logLevelAct)+" ]");
	bf.append(" "+getThreadTime()+" ");
	if (message != null) 
		bf.append(message.toString()+" ");
	if (exception != null)
		bf.append(getExceptionString(exception));  	
	if(logFileWriter != null)
	{
	  try
	  {
		logFileWriter.write(bf.toString(),0,bf.length());
		logFileWriter.newLine();
		logFileWriter.flush();
	
	  }
	  catch(IOException ioe)
	  {
		  System.err.println();
//		  OSLogData.syslog(className,"logDataPrint",OSLogData.SYSLOG_WARN,"INTERNAL_UNKNOWN_WARN",this.getExceptionString(ioe));
	  }
	  catch(Exception e)
	  {
		  System.err.println();
//		  OSLogData.syslog(className,"logDataPrint",OSLogData.SYSLOG_WARN,"INTERNAL_UNKNOWN_WARN",this.getExceptionString(e));
	  }
	}
	else { 
		System.err.println();
//		OSLogData.syslog(className,"logDataPrint",OSLogData.SYSLOG_WARN,"INTERNAL_UNKNOWN_WARN", new String("Surprising Error"));
	}
 }
/*get the name and time of the thead for logging*/

 private synchronized String getThreadTime() 
 {
   return 	"Time : "+((Calendar.getInstance()).getTime()).toString();
   //return	"Thread : N";
 }

 /*Extract the Exception into a string format*/
 public String getExceptionString(Throwable excp)
 {
	StringWriter sw = new StringWriter();
	
	PrintWriter pw = new PrintWriter(sw);
	
	excp.printStackTrace(pw);
	
	return sw.getBuffer().toString();
 }
 /*Receive logLevel in String format*/
 private String getlogDataLevelInfo(int level)
 {
   String s = "";
   switch (level)
   {
    case LOGDATA_LEVEL_NONE:   
    				s = "NONE";
				break;
    case LOGDATA_LEVEL_INFO:   
    				s = "INFO ";
				break;
    case LOGDATA_LEVEL_DEBUG:   
    				s = "DEBUG";
				break;
    case LOGDATA_LEVEL_ERROR:   
    				s = "ERROR";
				break;
   }
   return s;  
 }
 /*Receive logLEvel in int format*/
 private int getlogDataLevelValue(String level)
 {
 	int logDataLevel = 0;
   	
	if(level.equals("DEBUG")) 
		logDataLevel = LOGDATA_LEVEL_DEBUG;
	else if(level.equals("INFO")) 
		logDataLevel = LOGDATA_LEVEL_INFO;
	else if(level.equals("ERROR"))
		logDataLevel = LOGDATA_LEVEL_ERROR;
	else logDataLevel = LOGDATA_LEVEL_NONE;
	
	return logDataLevel;
 }
 
  public void crearMessageEXC(MbMessageAssembly assemblyOut, Throwable e){
		
		logData_Debug("Entra Metodo crearMensajeEXC(Exception)");
		
		try {
			MbMessage excepMessage = assemblyOut.getExceptionList();
			MbElement outRoot = excepMessage.getRootElement();
			
			MbElement ini = outRoot.createElementAsLastChild(MbElement.TYPE_NAME,"RecoverableException",null);
			ini.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Label", e.getLocalizedMessage());
			ini.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Text", e.getMessage());
			
			
			Throwable eaux = e.getCause();
			while (eaux != null){
				ini = ini.createElementAsLastChild(MbElement.TYPE_NAME,"RecoverableException",null);
				ini.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Label", e.getLocalizedMessage());
				ini.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Text", e.getMessage());
				eaux = e.getCause();
			}
			
			
		}catch (Exception ex) {
			logData_Error("Error Metodo crearMensajeEXC", ex);
			e.printStackTrace();
		}

	}
	
	void traverse(MbElement ini, MbException ex, int level)
	  {
	    if(ex != null)
	      {
	        // Do whatever action here
	    	try{
		    	ini.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Level", level);
				ini.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Function", ex.getMethodName());
				ini.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Catalog", ex.getMessageSource());
				ini.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Number", ex.getMessageKey());
				ini.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Text", ex.getTraceText());
				
				Object ob[] = ex.getInserts();
				int size = ob.length;
				
				for(int i = 0; i < size; i++){
					
					MbElement inst = ini.createElementAsLastChild(MbElement.TYPE_NAME,"Insert",null);
					inst.createElementAsLastChild(MbElement.TYPE_NAME_VALUE, "Text",ob[i].toString());
		        	
		        }
		        // traverse the hierarchy
		        MbException e[] = ex.getNestedExceptions();
		        size = e.length;
		        for(int i = 0; i < size; i++){
		        	MbElement ini2 = ini.createElementAsLastChild(MbElement.TYPE_NAME,"MessageException",null);
		        	traverse(ini2, e[i], level + 1);
		        	
		        }
	        
	        }catch (Exception exxxx) {
					logData_Info("FALLA TRA" + exxxx.toString());
	        }    
	      }
	  }

	
	public void crearMessageEXC(MbMessageAssembly assemblyOut, MbBrokerException e){
		
		logData_Debug("Entra Metodo crearMensajeEXC(MbBrokerException)");
		
		try {
			MbMessage excepMessage = assemblyOut.getExceptionList();
			MbElement outRoot = excepMessage.getRootElement();
			
			MbElement ini = outRoot.createElementAsLastChild(MbElement.TYPE_NAME,"RecoverableException",null);
			MbException ee = e.getNestedException();
			traverse(ini, ee, 0);
			
			
			
		}catch (Exception ex) {
			logData_Error("Error Metodo crearMensajeEXC2", ex);
			e.printStackTrace();
		}

	}
	

}
